using System;

namespace Pinwheel.LSerialize
{
    public interface ILFormatterRegister
    {
    }
    
    public interface ILSerializable : ILFormatterRegister
    {
    }
    
    public interface ILSerializable<T> : ILSerializable
    {
    }
    
    [Preserve]
    public unsafe interface ILFormatter
    {
        [Preserve]
        void Serialize(LSerializeContext* context, LStreamWriter* writer, ref object value);
        
        [Preserve]
        void Deserialize(LSerializeContext* context, LStreamReader* reader, ref object value);
    }
    
    [Preserve]
    public unsafe interface ILFormatter<T>
    {
        [Preserve]
        void Serialize(LSerializeContext* context, LStreamWriter* writer, ref T value);
        
        [Preserve]
        void Deserialize(LSerializeContext* context, LStreamReader* reader, ref T value);
    }
    
    [Preserve]
    public abstract unsafe class LFormatter<T> : ILFormatter<T>, ILFormatter
    {
        [Preserve]
        public abstract void Serialize(LSerializeContext* context, LStreamWriter* writer, ref T value);
        
        [Preserve]
        public abstract void Deserialize(LSerializeContext* context, LStreamReader* reader, ref T value);

        [Preserve]
        void ILFormatter.Serialize(LSerializeContext* context, LStreamWriter* writer, ref object value)
        {
            var v = (value == null)
                ? default(T)
                : (T)value;
            Serialize(context, writer, ref v);
        }

        [Preserve]
        void ILFormatter.Deserialize(LSerializeContext* context, LStreamReader* reader, ref object value)
        {
            var v = (value == null)
                ? default(T)
                : (T)value;
            Deserialize(context, reader, ref v);
            value = v;
        }
    }
}
